package org.snusmumr.android.media;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.snusmumr.android.media.bean.LabelModel;
import org.snusmumr.android.media.data.DatabaseProvider;
import org.snusmumr.android.media.data.DatabaseProvider.DatabaseMode;
import org.snusmumr.android.media.data.MediaColumns;
import org.snusmumr.android.media.data.SaveMediaItemOperation;
import org.snusmumr.android.media.data.SaveMediaItemOperation.MediaItemContainer;
import org.snusmumr.android.media.data.UnlentItemsOperation;
import org.snusmumr.android.media.dialog.SelectLabelDialog;
import org.snusmumr.android.media.dialog.SelectLabelDialog.OnLabelsSelectListener;
import org.snusmumr.android.media.util.Utils;
import org.snusmumr.android.media.widget.LabelView;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FilterQueryProvider;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.CursorToStringConverter;
import android.widget.TextView;

public class MediaItemContent extends Activity implements MediaItemContainer {
	private static final String TAG = MediaItemContent.class.getSimpleName();
	
	private DatabaseProvider dbProvider;
	private SimpleCursorAdapter authorAdapter;
	
	private ArrayList<LabelModel> labels;
	private long itemId;
	private Long authorId;
	private long categoryId;
	private DateFormat dateFormat;
	private DirtyWatcher dirtyWatcher;
	
	
	private OnLabelsSelectListener onLabelsSelectListener = new OnLabelsSelectListener() {
		@Override
		public void onLabelsSelected(List<LabelModel> selectedLabels) {
			labels.clear();
			labels.addAll(selectedLabels);
			drawLabels();
		}
	};
	
	private static class DirtyWatcher implements TextWatcher {
		private boolean dirty;
		
		public void init() {
			dirty = false;
		}
		
		public boolean isDirty() {
			return dirty;
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			dirty = true;
		}

		@Override
		public void afterTextChanged(Editable s) {}
		
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.media_item_content);
		
		final Bundle extras = getIntent().getExtras();
		this.itemId = extras.getLong(Constants.KEY_ID, -1);
		this.categoryId = extras.getLong(Constants.KEY_PARENT_ID);
		this.labels = new ArrayList<LabelModel>();
		this.dateFormat = android.text.format.DateFormat.getMediumDateFormat(getContext().getApplicationContext());
		this.dirtyWatcher = new DirtyWatcher();
		
		Button btnSetLabels = (Button) findViewById(R.id.btn_media_content_set_labels);
		btnSetLabels.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new SelectLabelDialog(MediaItemContent.this, onLabelsSelectListener).show();
			}
		});
		
		Button saveBtn = (Button) findViewById(R.id.btn_media_content_save);
		saveBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				save();
			}
		});
		
		Button cancelBtn = (Button) findViewById(R.id.btn_media_content_cancel);
		cancelBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				cancel();
			}
		});
		
		Button getBackBtn = (Button) findViewById(R.id.btn_media_content_unlend);
		getBackBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				unlendItem();
			}
		});
		
		
		dbProvider = DatabaseProvider.getInstance(this);
	}
	
	private void cancel() {
		if(dirtyWatcher.isDirty()) {
			new AlertDialog.Builder(MediaItemContent.this)
	        .setIcon(android.R.drawable.ic_dialog_alert)
	        .setTitle(R.string.save_changes_title)
	        .setMessage(R.string.confirm_save_changes_msg)
	        .setCancelable(true)
	        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
	            @Override
	            public void onClick(DialogInterface dialog, int which) {
	            	save();
	            }
	        })
	        .setNegativeButton(android.R.string.no, null)
	        .show();
		} else
			MediaItemContent.this.onBackPressed();
	}
	
	private void unlendItem() {
		new AlertDialog.Builder(MediaItemContent.this)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(R.string.confirm_unlend_title)
        .setMessage(R.string.confirm_unlend_msg)
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            	final long[] selectedItems = new long[1];
				selectedItems[1] = itemId;
				if(dirtyWatcher.isDirty()) {
					boolean saved = new SaveMediaItemOperation(MediaItemContent.this).execute();
					if(! saved)
						return;
				}
				Boolean result = new UnlentItemsOperation(getContext(), selectedItems).execute();
				if(Boolean.TRUE.equals(result)) {
					MediaItemContent.this.onBackPressed();
				}
            }
        })
        .setNegativeButton(android.R.string.no, null)
        .show();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		releaseResources();
	}

	private void releaseResources() {
		Utils.closeCursor(authorAdapter);
		dbProvider.close();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		loadData();
	}
	
	private void loadData() {
		final Resources res = getResources();
		String name = "";
		String comment = "";
		Long authorId = null;
		String authorName = "";
		String labelsMask = null;
		String lentTo = null;
		String lentAt = null;
		labels.clear();
		if(itemId != -1L) {
			SQLiteDatabase database = dbProvider.getDatabase(DatabaseMode.Read);
			Cursor c = database.rawQuery(res.getString(R.string.sql_fetch_item_data), 
								new String[]{String.valueOf(itemId)});
			if(c != null && c.moveToFirst()) {
				name = c.getString(0);
				comment = c.getString(1);
				authorId = c.getLong(2);
				authorName = c.getString(3);
				labelsMask = c.getString(4);
				lentTo = c.getString(c.getColumnIndex(MediaColumns.LENT_TO_NAME));
				lentAt = c.getString(c.getColumnIndex(MediaColumns.LEND_DATE));
			}
			if(c != null)
				c.close();
			
			String labelsId = Utils.getBitsAsString(labelsMask);
			String query = MediaColumns._ID;
			if(! Utils.isEmpty(labelsId))
				query += " in(" + labelsId + ')';
			else
				query += "=-100";
			c = database.query(Constants.DB_TABLE_LABEL, 
					new String[]{MediaColumns._ID,
									MediaColumns.NAME,
									MediaColumns.COLOR}, 
					query, null, null, null, MediaColumns.NAME);
			if(c != null) {
				while (c.moveToNext()) {
					LabelModel lm = new LabelModel(c.getLong(0), c.getString(1), c.getInt(2));
					labels.add(lm);
				}
				c.close();
			}
		}
		initContent(name, comment, authorName, authorId, lentTo, lentAt);
		
		if(authorAdapter == null)
			initAuthorAdapter();
	}

	private void initAuthorAdapter() {
		final Resources res = getResources();
		Cursor c = dbProvider.getDatabase(DatabaseMode.Read).rawQuery(res.getString(R.string.sql_fetch_authors), null);
		startManagingCursor(c);
		authorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, c, new String[]{"name"}, new int[]{android.R.id.text1});
		AutoCompleteTextView authorEditView = (AutoCompleteTextView)findViewById(R.id.ed_media_content_author);
		authorEditView.setAdapter(authorAdapter);
		
		authorEditView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> listView, View view,
                        int position, long id) {
                Cursor cursor = (Cursor) listView.getItemAtPosition(position);
                MediaItemContent.this.authorId = cursor.getLong(0);
                Log.d(TAG, "authorId set to " + MediaItemContent.this.authorId);
            }
        });
		
		authorAdapter.setCursorToStringConverter(new CursorToStringConverter() {
            public String convertToString(Cursor cursor) {
                return cursor.getString(1);
            }
        });
		
		authorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
			@Override
			public Cursor runQuery(CharSequence constraint) {
				Cursor cursor;
				SQLiteDatabase database = dbProvider.getDatabase(DatabaseMode.Read);
				if(Utils.isEmpty(constraint)) {
					cursor = database.rawQuery(res.getString(R.string.sql_fetch_authors), null);
				} else {
					String query = "SELECT _id, name FROM author WHERE name like '%"
						+ constraint + "%' ORDER BY name";
					cursor = database.rawQuery(query, null);
				}
				MediaItemContent.this.startManagingCursor(cursor);
				return cursor;
			}
		});
	}
	
	private void initContent(String name, 
			String comment, String authorName, Long authorId, String lentTo, String lentAt) {
		this.authorId = authorId;
		
		this.dirtyWatcher.init();
		initEditText(((EditText)findViewById(R.id.ed_media_content_title)), name);
		initEditText(((EditText)findViewById(R.id.ed_media_content_comment)), comment);
		initEditText(((EditText)findViewById(R.id.ed_media_content_author)), authorName);
//		((TextView)findViewById(R.id.ed_media_content_title)).setText(name);
//		((TextView)findViewById(R.id.ed_media_content_comment)).setText(comment);
//		((TextView)findViewById(R.id.ed_media_content_author)).setText(authorName);
		drawLabels();
		View lendPanel = findViewById(R.id.l_media_content_lend_panel);
		if(! Utils.isEmpty(lentAt)) {
			// show lend panel and set fields values
			lendPanel.setVisibility(View.VISIBLE);
			((TextView)findViewById(R.id.tv_media_content_lent_to_friend)).setText(lentTo);
			
			String lendDateStr = null;
			try {
				Date lendDate = Utils.getDateFromDB(lentAt);
				if(lendDate != null) 
					lendDateStr = dateFormat.format(lendDate);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			((TextView)findViewById(R.id.tv_media_content_lent_date)).setText(lendDateStr);
		} else {
			// hide lend panel
			lendPanel.setVisibility(View.INVISIBLE);
		}
	}
	
	private void initEditText(EditText ed, String value) {
		ed.setText(value);
		ed.addTextChangedListener(dirtyWatcher);
	}

	private void drawLabels() {
		if(labels == null)
			return;
		
		final LinearLayout layout = (LinearLayout) MediaItemContent.this.findViewById(R.id.lt_media_content_labels);
		int cnt = layout.getChildCount();
		for(int i=0; i<cnt; i++) {
			View child = layout.getChildAt(i);
			if(! (child instanceof Button)) {
				layout.removeViewAt(i);
				i--;
				cnt--;
			}
		}
		
		int size = labels.size();
		for(int i=0; i<size; i++) {
			LabelModel m = labels.get(i);
			final LabelView labelView = new LabelView(MediaItemContent.this);
			labelView.setColorLabel(m.getColor());
			labelView.setText(m.getValue());
			final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
			layoutParams.leftMargin=20;
			layout.addView(labelView, layoutParams);
		}
	}

	@Override
	public Long getAuthorId() {
		return authorId;
	}

	@Override
	public void setAuthorId(Long authorId) {
		this.authorId = authorId;
	}

	@Override
	public long getCategoryId() {
		return categoryId;
	}

	@Override
	public long getItemId() {
		return itemId;
	}

	@Override
	public void setItemId(long itemId) {
		this.itemId = itemId;
	}

	@Override
	public ArrayList<LabelModel> getLabels() {
		return labels;
	}

	@Override
	public String getAuthorName() {
		return ((AutoCompleteTextView)findViewById(R.id.ed_media_content_author)).getText().toString();
	}

	@Override
	public String getName() {
		return ((TextView)findViewById(R.id.ed_media_content_title)).getText().toString();
	}

	@Override
	public String getComment() {
		return ((TextView)findViewById(R.id.ed_media_content_comment)).getText().toString();
	}
	
	@Override
	public Context getContext() {
		return this;
	}

	private void save() {
		boolean saved = new SaveMediaItemOperation(MediaItemContent.this).execute();
		if(saved) {
			MediaItemContent.this.onBackPressed();
		}
	}
}
